class Node{
    constructor(element){
        this.element = element;
        this.prev = null;
        this.next = null;
    }
}

//双向链表
class DoubleList{
    constructor(){
        this.head = null;
        this.tail = null;
        this.count = 0;
    }

    //向链表的末尾添加节点
    push(element){
        let node = new Node(element);

        //1.判断双向链表是否为空
        if(this.head === null){
            this.head = node;
            this.tail = node;
        }else{
            let last = this.tail;
            this.tail = node;
            last.next = node;
            node.prev = last;
        }

        this.count++;

    }

    //循环迭代链表查找指定元素
    getElementAt(index){
        let current = this.head;
        for(let i = 0;i < index;i++){
            current = current.next;
        }
        return current
    }

    //在指定位置插入节点
    insert(element,index){
        //1.边界值的判断
        if(index >= 0 && index <= this.count){
           
            let node = new Node(element);

            if(index === 0){
                //1.在链表开头插入
                if(this.head === null){
                    //1.1 链表为空
                    this.head = node;
                    this.tail = node;
                }else{
                    //1.2 链表不为空
                    let current = this.head;
                    node.next = current;
                    current.prev = node;
                    this.head = node;
                }
            }else if(index === this.count){
                //2.在链表结尾插入
                let last = this.tail;
                last.next = node;
                node.prev = last;

            }else{
                //3.在链表中间插入
                let prev = this.getElementAt(index - 1);
                let current = prev.next;
                prev.next = node;
                node.prev = prev;
                current.prev = node;
                node.next = current;
            }

            this.count++;
        }else{
            return false
        }
    }

    //打印的方法
    print(){
        let current = this.head;
        if(current){
            while(current.next != null){
                console.log(current);
                current = current.next;
            }
            console.log(current)
        }
    }

    //删除
    removeAt(index){
        //1.边界值的判断
        if(index >= 0 && index <= this.count){
            let current = this.head;
            if(index === 0){
                this.head = current.next;
                if(this.count === 1){
                    this.tail = null;
                }else{
                    this.head.prev = null;
                }
            }else if(index === this.count-1){
                current = this.tail;
                this.tail = current.prev;
                this.tail.next = null;
            }else{
                current = this.getElementAt(index);
                const previous = current.prev;
                previous.next = current.next;
                current.next.prev = previous;
            }
            this.count--;
            return current.element
        }else{
            return undefined
        }
    }

    //查找下标
    indexOf(element){
        let current = this.head;
        for(let i = 0;i<this.count;i++){
            if(current.element === element){
                return i
            }
            current = current.next;
        }
        return -1
    }

    //删除元素
    remove(element){
        let index = this.indexOf(element);
        this.removeAt(index);
    }

    //获取头元素
    getHead(){
        return this.head;
    }

    //获取尾元素
    getTail(){
        return this.tail;
    }

    //获取元素个数
    size(){
        return this.count;
    }

    //获取链表是否为空
    isEmpty(){
        return this.count === 0;
    }

    //清空链表
    clear(){
        this.head = null;
        this.tail = null;
        this.count = 0;
    }

}

let d = new DoubleList();

d.push('a');

d.push('c');

d.push('d');

// d.insert('b',1);

// console.log(d);

// d.clear();

d.remove('c');

console.log(d.indexOf('d'));

d.print();

/***
 * 作业:
 * 
 *  1.单向链表  双向链表
 * 
 *  2.周考题 
 * 
 * */ 